﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
using System.Text;
using System.Threading.Tasks;

namespace StyleMVVM.DependencyInjection
{
	public sealed class SingletonLifeCycleContainer : ILifeCycleContainer
	{
		private volatile object sharedObject;
		private readonly object lockObject = new object();
		private IDisposalScope disposalScope = new DisposalScope();

		public SingletonLifeCycleContainer()
		{
		}

		public SingletonLifeCycleContainer(object sharedObject)
		{
			this.sharedObject = sharedObject;
		}

		public object RetrieveObject(IExportStrategy strategy,
											  ExportLifeCycleMethod exportMethod,
											  IDependencyInjectionContainer container,
											  IInjectionContext injectionContext,
											  [ReadOnlyArray] object[] constructorParams)
		{
			if (sharedObject == null)
			{
				lock (lockObject)
				{
					if (sharedObject == null)
					{
						IDisposalScope oldScope = injectionContext.DisposalScope;

						injectionContext.DisposalScope = disposalScope;

						sharedObject = exportMethod(injectionContext, constructorParams);

						injectionContext.DisposalScope = oldScope;
					}
				}
			}

			return sharedObject;
		}

		public void Shutdown()
		{
			sharedObject = null;

			disposalScope.Dispose();

			disposalScope = null;
		}
	}
}
